target = [[1, 5, 3],
          [1 / 5, 1, 1 / 3],
          [1 / 3, 3, 1]]
programme1 = [[1, 1 / 7, 1 / 5],
              [7, 1, 3],
              [5, 1 / 3, 1]]
programme2 = [[1, 2, 3],
              [1 / 2, 1, 2],
              [1 / 3, 1 / 2, 1]]
programme3 = [[1, 5, 3],
              [1 / 5, 1, 1 / 2],
              [1 / 3, 2, 1]]
programmes = [programme1, programme2, programme3]


def completion(matrix_half):  # 补全半个矩阵
    length = len(matrix_half)
    for i in range(length):
        for j in range(length):
            if matrix_half[i][j] == 1 and matrix_half[j][i] != 1:
                matrix_half[i][j] = 1 / matrix_half[j][i]
            if i == j:
                matrix_half[i][j] = 1
    return matrix_half


def matrix_transpose(matrix):  # 矩阵转置
    return [[matrix[j][i] for j in range(len(matrix))] for i in range(len(matrix[0]))]


def matrix_multiplication(matrix_2, matrix_1):  # 二维与一维的矩阵乘法
    return [sum(matrix_2[j][i] * matrix_1[i] for i in range(len(matrix_1))) for j in range(len(matrix_2))]


def summation(matrix_b):  # 求和法
    matrix_b = matrix_transpose(matrix_b)
    b = [[i for i in j] for j in matrix_b]  # 深度copy 等同于 b = copy.deepcopy(matrix_b)
    matrix_b = [[matrix_b[i][j] / sum(b[i]) for j in range(len(matrix_b))] for i in range(len(matrix_b[0]))]  # 归一化
    matrix_b = matrix_transpose(matrix_b)
    v = [sum(i) for i in matrix_b]  # 按行求和得到v
    w = [i / sum(v) for i in v]  # 归一化得到w
    return v, w


def rooting(matrix_b):  # 求根法
    def q_root(list0):  # 相乘再开方
        quadrature = 1
        for i in list0:
            quadrature *= i
        root = quadrature ** (1 / len(list0))
        return root

    v = [q_root(i) for i in matrix_b]  # 按行相乘再开方
    w = [i / sum(v) for i in v]  # 归一化得到w
    return v, w


def check(matrix_a, method=1):  # 一致性检验,1求根法，0求和法
    ri = {1: 0, 2: 0, 3: 0.58, 4: 0.92, 5: 1.12, 6: 1.24, 7: 1.32, 8: 1.41, 9: 1.45}  # RI表
    weight = rooting(matrix_a)[1] if method == 1 else summation(matrix_a)[1]
    a_w = matrix_multiplication(matrix_a, weight)
    lambda_max = sum([a_w[i] / weight[i] for i in range(len(weight))]) / len(a_w)
    if len(a_w) != 1:
        ci = (lambda_max - len(a_w)) / (len(a_w) - 1)  # CI值
    else:
        ci = 0
    ri = ri[len(a_w)]  # RI值
    if ri != 0:
        cr = ci / ri  # CR值
    else:
        cr = 0.0001
    best = weight.index(max(weight))
    return weight, a_w, lambda_max, ci, ri, cr, best, True if cr < 0.1 else False


def check_all(matrix_, matrix_s):  # 层次总排序组合一致性检验
    w_ = check(matrix_)[0]  # 上一层的一致性检验值
    ci = sum([w_[i] * check(matrix_s[i])[3] for i in range(len(matrix_s))])
    ri = sum([w_[i] * check(matrix_s[i])[4] for i in range(len(matrix_s))])  # 这一层的一致性检验值权重和
    if ri != 0:
        cr = ci / ri
    else:
        cr = 0
    return cr, True if cr < 0.1 else False


def choice_best(target_, programmes_):
    t = check(target_)[0]
    p = matrix_transpose([check(i)[0] for i in programmes_])
    w = matrix_multiplication(p, t)
    best = w.index(max(w))
    cr, check_ = check_all(target_, programmes_)
    return t, p, w, best, cr, check_


if __name__ == '__main__':
    print(check_all(target, [[[1]]]))
